package com.common.www.service.programme;


import org.springframework.boot.base.jpa.service.BaseLogicService;
import com.common.www.bean.entity.programme.XfgcPrecipitate;
import com.common.www.bean.entity.project.*;
import com.common.www.bean.entity.tabulation.InnerBidBaseTabulation;
import com.common.www.bean.entity.tabulation.InnerTabulation;
import com.common.www.bean.entity.tabulation.OuterTabulation;
import com.common.www.bean.entity.tabulation.XfgcTabulation;
import com.common.www.bean.vo.ComprehensiveUnitPriceCollectVo;
import com.common.www.bean.vo.FeXiExtractingVo;
import com.common.www.repository.programme.XfgcPrecipitateRepository;
import com.common.www.service.project.ProjectService;
import com.common.www.service.project.SupplyCompanyService;
import com.common.www.service.project.XfgcBasicService;
import com.common.www.service.project.XfgcBiddingCompanyService;
import com.common.www.service.tabulation.XfgcTabulationService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Column;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.common.www.service.tabulation.InnerTabulationService.createCellAddStype;


@Service
@Transactional
public class XfgcPrecipitateService extends BaseLogicService<XfgcPrecipitate, Long> {
    @Autowired
    private XfgcBiddingCompanyService biddingCompanyService;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private SupplyCompanyService supplyCompanyService;
    @Autowired
    private XfgcTabulationService xfgcTabulationService;
    @Autowired
    private XfgcBasicService xfgcBasicService;

    @Autowired
    private XfgcPrecipitateRepository repository;

    @Override
    public XfgcPrecipitateRepository getRepository() {
        return repository;
    }

    /**
     * 计算并保存定标最终沉淀数据--首次
     *
     * @param projectId
     */
    public void handlePrecipitate(Long projectId) {
        Project project = projectService.findOne(projectId);
        XfgcBasic xfgcBasic = xfgcBasicService.getRepository().findByFlagAndProjectId(1, projectId);
        if (xfgcBasic == null) {
            throw new ServiceException("消防工程没有配置项目及业态等信息");
        }
        BigDecimal diXiaShiArea = (xfgcBasic.getDiXiaShi() != null && xfgcBasic.getDiXiaShi().getYeTaiArea() != null) ? xfgcBasic.getDiXiaShi().getYeTaiArea() : BigDecimal.ZERO;
        BigDecimal gaoCengArea = (xfgcBasic.getGaoCeng() != null && xfgcBasic.getGaoCeng().getYeTaiArea() != null) ? xfgcBasic.getGaoCeng().getYeTaiArea() : BigDecimal.ZERO;
        BigDecimal xiaoGaoCengArea = (xfgcBasic.getXiaoGaoCeng() != null && xfgcBasic.getXiaoGaoCeng().getYeTaiArea() != null) ? xfgcBasic.getXiaoGaoCeng().getYeTaiArea() : BigDecimal.ZERO;
        BigDecimal yangFangArea = (xfgcBasic.getYangFang() != null && xfgcBasic.getYangFang().getYeTaiArea() != null) ? xfgcBasic.getYangFang().getYeTaiArea() : BigDecimal.ZERO;
        BigDecimal shangYeArea = (xfgcBasic.getShangYe() != null && xfgcBasic.getShangYe().getYeTaiArea() != null) ? xfgcBasic.getShangYe().getYeTaiArea() : BigDecimal.ZERO;
        BigDecimal bieShuArea = (xfgcBasic.getBieShu() != null && xfgcBasic.getBieShu().getYeTaiArea() != null) ? xfgcBasic.getBieShu().getYeTaiArea() : BigDecimal.ZERO;
        BigDecimal gongYuArea = (xfgcBasic.getGongYu() != null && xfgcBasic.getGongYu().getYeTaiArea() != null) ? xfgcBasic.getGongYu().getYeTaiArea() : BigDecimal.ZERO;
        BigDecimal youErYuanArea = (xfgcBasic.getYouErYuan() != null && xfgcBasic.getYouErYuan().getYeTaiArea() != null) ? xfgcBasic.getYouErYuan().getYeTaiArea() : BigDecimal.ZERO;
        //先查询剩下的未弃标或淘汰的供应商
        List<XfgcBiddingCompany> biddingCompanies = biddingCompanyService.getRepository().findByFlagAndProjectIdAndBidStatus(1, projectId, 1);
        List<Long> ids = new ArrayList<>();
        for (XfgcBiddingCompany company : biddingCompanies) {
            ids.add(company.getId());
        }
        Long[] idsArray = new Long[ids.size()];
        idsArray = ids.toArray(idsArray);
        //供应商清单
        HashMap hashMap = new HashMap();
        hashMap.put("xfgcBiddingCompany.id_in", idsArray);
        hashMap.put("xfgcBiddingCompany.project.id", projectId);
        hashMap.put("jieDuan", 5);
        hashMap.put("flag", 1);
        List<XfgcTabulation> tabulationList = xfgcTabulationService.getListLogic(hashMap, null);
        //tabulationList先按供应商分组，如果有多个供应商则返回提示(定标阶段生成沉淀数据只能有一个供应商)
        Map<Long, List<XfgcTabulation>> companyList = tabulationList.stream().collect(Collectors.groupingBy(t -> t.getXfgcBiddingCompany().getId()));
        if (companyList.size() == 0) {
            throw new ServiceException("暂无供应商到达定标阶段");
        }
        if (companyList.size() > 1) {
            throw new ServiceException("定标阶段存在多个供应商，请确定定标唯一供应商");
        }
        //将tabulationList按系统分组后，将所需数据累加
        List<XfgcTabulation> tempTabulationList = new ArrayList<>();
        Map<String, List<XfgcTabulation>> xiTongList = tabulationList.stream().collect(Collectors.groupingBy(XfgcTabulation::getXiTongFenLei));
        for (Map.Entry<String, List<XfgcTabulation>> item : xiTongList.entrySet()) {
            String xiTong = item.getKey();
            List<XfgcTabulation> value = item.getValue();
            //合价-含增值税
            BigDecimal totalPriceHs = BigDecimal.ZERO;
            //合价-含增值税(地下室合计)
            BigDecimal totalPrice1 = BigDecimal.ZERO;
            //合价-含增值税(高层合计)
            BigDecimal totalPrice2 = BigDecimal.ZERO;
            //合价-含增值税(小高层合计)
            BigDecimal totalPrice3 = BigDecimal.ZERO;
            //合价-含增值税(洋房合计)
            BigDecimal totalPrice4 = BigDecimal.ZERO;
            //合价-含增值税(商业合计)
            BigDecimal totalPrice5 = BigDecimal.ZERO;
            //合价-含增值税(总平合计)
            BigDecimal totalPrice6 = BigDecimal.ZERO;
            //合价-含增值税(别墅合计)
            BigDecimal totalPrice7 = BigDecimal.ZERO;
            //合价-含增值税(公寓合计)
            BigDecimal totalPrice8 = BigDecimal.ZERO;
            //合价-含增值税(幼儿园合计)
            BigDecimal totalPrice9 = BigDecimal.ZERO;
            for (XfgcTabulation t : value) {
                if (t.getTotalPriceHs() != null) {
                    totalPriceHs = totalPriceHs.add(t.getTotalPriceHs());
                }
                if (t.getTotalPrice1() != null) {
                    totalPrice1 = totalPrice1.add(t.getTotalPrice1());
                }
                if (t.getTotalPrice2() != null) {
                    totalPrice2 = totalPrice2.add(t.getTotalPrice2());
                }
                if (t.getTotalPrice3() != null) {
                    totalPrice3 = totalPrice3.add(t.getTotalPrice3());
                }
                if (t.getTotalPrice4() != null) {
                    totalPrice4 = totalPrice4.add(t.getTotalPrice4());
                }
                if (t.getTotalPrice5() != null) {
                    totalPrice5 = totalPrice5.add(t.getTotalPrice5());
                }
                if (t.getTotalPrice6() != null) {
                    totalPrice6 = totalPrice6.add(t.getTotalPrice6());
                }
                if (t.getTotalPrice7() != null) {
                    totalPrice7 = totalPrice7.add(t.getTotalPrice7());
                }
                if (t.getTotalPrice8() != null) {
                    totalPrice8 = totalPrice8.add(t.getTotalPrice8());
                }
                if (t.getTotalPrice9() != null) {
                    totalPrice9 = totalPrice9.add(t.getTotalPrice9());
                }
            }
            XfgcTabulation temp = new XfgcTabulation();
            temp.setXiTongFenLei(xiTong);
            temp.setXfgcBiddingCompany(value.get(0).getXfgcBiddingCompany());
            temp.setTotalPriceHs(totalPriceHs);
            temp.setTotalPrice1(totalPrice1);
            temp.setTotalPrice2(totalPrice2);
            temp.setTotalPrice3(totalPrice3);
            temp.setTotalPrice4(totalPrice4);
            temp.setTotalPrice5(totalPrice5);
            temp.setTotalPrice6(totalPrice6);
            temp.setTotalPrice7(totalPrice7);
            temp.setTotalPrice8(totalPrice8);
            temp.setTotalPrice9(totalPrice9);
            tempTabulationList.add(temp);
        }
        //计算并生成定标时评标公司及清单沉淀数据
        for (XfgcTabulation temp : tempTabulationList) {
            //汇总
            BigDecimal basePriceA0 = BigDecimal.ZERO;
            BigDecimal sumArea = diXiaShiArea.add(gaoCengArea).add(xiaoGaoCengArea).add(yangFangArea).add(shangYeArea).add(bieShuArea).add(gongYuArea).add(youErYuanArea);
            if (temp.getTotalPriceHs() != null && sumArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA0 = temp.getTotalPriceHs().divide(sumArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(地下室合计)
            BigDecimal basePriceA1 = BigDecimal.ZERO;
            if (temp.getTotalPrice1() != null && diXiaShiArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA1 = temp.getTotalPrice1().divide(diXiaShiArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(高层合计)
            BigDecimal basePriceA2 = BigDecimal.ZERO;
            if (temp.getTotalPrice2() != null && gaoCengArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA2 = temp.getTotalPrice2().divide(gaoCengArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(小高层合计)
            BigDecimal basePriceA3 = BigDecimal.ZERO;
            if (temp.getTotalPrice3() != null && xiaoGaoCengArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA3 = temp.getTotalPrice3().divide(xiaoGaoCengArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(洋房合计)
            BigDecimal basePriceA4 = BigDecimal.ZERO;
            if (temp.getTotalPrice4() != null && yangFangArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA4 = temp.getTotalPrice4().divide(yangFangArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(商业合计)
            BigDecimal basePriceA5 = BigDecimal.ZERO;
            if (temp.getTotalPrice5() != null && shangYeArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA5 = temp.getTotalPrice5().divide(shangYeArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(总平合计)
            BigDecimal basePriceA6 = BigDecimal.ZERO;
            if (temp.getTotalPrice6() != null && diXiaShiArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA6 = temp.getTotalPrice6().divide(diXiaShiArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(别墅合计)
            BigDecimal basePriceA7 = BigDecimal.ZERO;
            if (temp.getTotalPrice7() != null && bieShuArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA7 = temp.getTotalPrice7().divide(bieShuArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(公寓合计)
            BigDecimal basePriceA8 = BigDecimal.ZERO;
            if (temp.getTotalPrice8() != null && gongYuArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA8 = temp.getTotalPrice8().divide(gongYuArea, RoundingMode.HALF_UP);
            }
            //合价-含增值税(幼儿园合计)
            BigDecimal basePriceA9 = BigDecimal.ZERO;
            if (temp.getTotalPrice9() != null && youErYuanArea.compareTo(BigDecimal.ZERO) != 0) {
                basePriceA9 = temp.getTotalPrice9().divide(youErYuanArea, RoundingMode.HALF_UP);
            }

            for (int i = 0; i < 10; i++) {
                XfgcPrecipitate precipitate = new XfgcPrecipitate();
                precipitate.setProject(project);
                precipitate.setSupplyCompany(temp.getXfgcBiddingCompany().getSupplyCompany());
                precipitate.setXiTong(temp.getXiTongFenLei());
                if (i == 0) {
                    precipitate.setYeTai("汇总");
                    precipitate.setBasePriceA(basePriceA0);
                }
                if (i == 1) {
                    precipitate.setYeTai("地下室");
                    if (xfgcBasic.getDiXiaShi() != null && xfgcBasic.getDiXiaShi().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA1);
                    }
                }
                if (i == 2) {
                    precipitate.setYeTai("高层");
                    if (xfgcBasic.getGaoCeng() != null && xfgcBasic.getGaoCeng().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA2);
                    }
                }
                if (i == 3) {
                    precipitate.setYeTai("小高层");
                    if (xfgcBasic.getXiaoGaoCeng() != null && xfgcBasic.getXiaoGaoCeng().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA3);
                    }
                }
                if (i == 4) {
                    precipitate.setYeTai("洋房");
                    if (xfgcBasic.getYangFang() != null && xfgcBasic.getYangFang().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA4);
                    }
                }
                if (i == 5) {
                    precipitate.setYeTai("商业");
                    if (xfgcBasic.getShangYe() != null && xfgcBasic.getShangYe().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA5);
                    }
                }
                if (i == 6) {
                    precipitate.setYeTai("总平");
                    if (xfgcBasic.getDiXiaShi() != null && xfgcBasic.getDiXiaShi().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA6);
                    }
                }
                if (i == 7) {
                    precipitate.setYeTai("别墅");
                    if (xfgcBasic.getBieShu() != null && xfgcBasic.getBieShu().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA7);
                    }
                }
                if (i == 8) {
                    precipitate.setYeTai("公寓");
                    if (xfgcBasic.getGongYu() != null && xfgcBasic.getGongYu().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA8);
                    }
                }
                if (i == 9) {
                    precipitate.setYeTai("幼儿园");
                    if (xfgcBasic.getYouErYuan() != null && xfgcBasic.getYouErYuan().getYeTaiArea() != null) {
                        precipitate.setBasePriceA(basePriceA9);
                    }
                }
                save(precipitate);
            }
        }
    }


    /**
     * 计算并保存定标最终沉淀数据--添加对比项目
     *
     * @param projectId
     * @param choiceProjectId
     * @param choiceSupplyCompanyId
     */
    public void handlePrecipitateToProject(Long projectId, Long choiceProjectId, Long choiceSupplyCompanyId) {
        List<XfgcPrecipitate> precipitateList = getRepository().findByFlagAndProjectId(1, projectId);
        List<XfgcPrecipitate> historyPrecipitateList = getRepository().findByFlagAndProjectIdAndSupplyCompanyId(1, choiceProjectId, choiceSupplyCompanyId);
        if (precipitateList.size() > 0 && historyPrecipitateList.size() > 0) {
            for (XfgcPrecipitate temp : precipitateList) {
                for (XfgcPrecipitate history : historyPrecipitateList) {
                    if (temp.getXiTong().equals(history.getXiTong()) && temp.getYeTai().equals(history.getYeTai())) {
                        temp.setChoiceProject(history.getProject());
                        temp.setChoiceSupplyCompany(history.getChoiceSupplyCompany());
                        temp.setHistoryBasePriceB(history.getBasePriceA());
                        if (temp.getBasePriceA() != null && history.getBasePriceA() != null) {
                            temp.setAbPrice(temp.getBasePriceA().subtract(history.getBasePriceA()));
                        }
                    }
                }
            }
            repository.saveAll(precipitateList);
        }
    }


    /**
     * 选择项目
     *
     * @param projectId
     * @return
     */
    public List<Map<String, Object>> choiceProject(Long projectId) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        HashMap hashMap = new HashMap();
        hashMap.put("project.flag", 1);
        hashMap.put("project.id_ne", projectId);
        hashMap.put("flag", 1);
        hashMap.put("bidStatus", 1);
        List<XfgcBiddingCompany> companyList = biddingCompanyService.queryToList(hashMap, null);
        for (XfgcBiddingCompany company : companyList) {
            List<XfgcTabulation> dbTabulationList = xfgcTabulationService.getRepository().findByFlagAndXfgcBiddingCompanyIdAndJieDuan(1, company.getId(), 5);
            if (dbTabulationList.size() == 0) {
                continue;
            } else {
                Map<String, Object> tempMap = new HashMap<>();
                tempMap.put("project", company.getProject());
                tempMap.put("supplyCompany", company.getSupplyCompany());
                tempMap.put("biddingCompany", company);
                mapList.add(tempMap);
            }
        }
        return mapList;
    }


    /**
     * 组装定标沉淀数据
     *
     * @param dbList
     * @return
     */
    public List<Map<String, Object>> getXfgcAssembleSjcdList(List<XfgcPrecipitate> dbList) {
        //按供应商分组
        List<Map<String, Object>> mapList = new ArrayList<>();
        Map<Long, List<XfgcPrecipitate>> suNameList = dbList.stream().collect(Collectors.groupingBy(vo -> vo.getSupplyCompany().getId()));
        int index = 0;
        for (Map.Entry<Long, List<XfgcPrecipitate>> sItem : suNameList.entrySet()) {
            index++;
            List<XfgcPrecipitate> tempList = new ArrayList<>();
            tempList = sItem.getValue();
            //固定排序
            List<XfgcPrecipitate> sortedList = tempList.stream()
                    .sorted(Comparator.comparing(XfgcPrecipitate::getXiTong))
                    .collect(Collectors.toList());
            Map<String, Object> tempMap = new HashMap<>();
            tempMap.put("count", index);
            tempMap.put("supplyCompany", sortedList.get(0).getSupplyCompany());
            tempMap.put("dataChenDian", sortedList);
            mapList.add(tempMap);
        }
        return mapList;
    }


    /**
     * 导出定标阶段数据沉淀
     *
     * @param mapList
     * @return
     */
    public XSSFWorkbook exportDb(List<Map<String, Object>> mapList) {
        XSSFWorkbook workbook = new XSSFWorkbook();
        for (int i = 0; i < mapList.size(); i++) {
            Map<String, Object> map = mapList.get(i);
            Object supplyCompanyObj = map.get("supplyCompany");
            String sheetName = "";
            if (supplyCompanyObj instanceof SupplyCompany) { // 假设对象类型是 SupplyCompany
                SupplyCompany supplyCompany = (SupplyCompany) supplyCompanyObj;
                sheetName = supplyCompany.getName();
            }
            Sheet sheet = workbook.createSheet(sheetName);
            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(HorizontalAlignment.CENTER); // 居中
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 居中
            // 创建日期格式
            CellStyle cellDateStyle = workbook.createCellStyle();
            CreationHelper createHelper = workbook.getCreationHelper();
            cellDateStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-mm-dd hh:mm:ss"));

            //边框
            cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle.setBorderRight(BorderStyle.THIN);//右边框
            cellDateStyle.setBorderBottom(BorderStyle.THIN); //下边框
            cellDateStyle.setBorderLeft(BorderStyle.THIN);//左边框
            cellDateStyle.setBorderTop(BorderStyle.THIN);//上边框
            cellDateStyle.setBorderRight(BorderStyle.THIN);//右边框

            // 生成表头
            Row row0 = sheet.createRow(0);
            createCellAddStype(row0, 0, cellStyle).setCellValue("系统");
            createCellAddStype(row0, 1, cellStyle).setCellValue("业态");
            createCellAddStype(row0, 2, cellStyle).setCellValue("本项目定标单方A（元/m2）");
            createCellAddStype(row0, 3, cellStyle).setCellValue("历史项目单方B（元/m2）");
            createCellAddStype(row0, 4, cellStyle).setCellValue("差异单方A-B（元/m2）");
            createCellAddStype(row0, 5, cellStyle).setCellValue("差异分析");

            // 生成数据行
            Integer rowIndex = 1;
            Collection<?> sValueCollection = (Collection<?>) mapList.get(i).get("dataChenDian");
            for (Object sValueObj : sValueCollection) {
                // sValueObj 是自定义对象
                if (sValueObj instanceof XfgcPrecipitate) {
                    XfgcPrecipitate item = (XfgcPrecipitate) sValueObj;
                    Row row = sheet.createRow(rowIndex);
                    createCellAddStype(row, 0, cellStyle).setCellValue(item.getXiTong());
                    createCellAddStype(row, 1, cellStyle).setCellValue(item.getYeTai());
                    createCellAddStype(row, 2, cellStyle).setCellValue(item.getBasePriceA() != null ? item.getBasePriceA().toString() : "0");
                    createCellAddStype(row, 3, cellStyle).setCellValue(item.getHistoryBasePriceB() != null ? item.getHistoryBasePriceB().toString() : "0");
                    createCellAddStype(row, 4, cellStyle).setCellValue(item.getAbPrice() != null ? item.getAbPrice().toString() : "0");
                    createCellAddStype(row, 5, cellStyle).setCellValue(item.getChaYiFenXi());
                    rowIndex++;
                }
            }
        }
        return workbook;
    }


}
